"""告警管理器模块"""

import cv2
import numpy as np
from typing import Dict, List, Tuple, Optional, Any
import time
import uuid
from datetime import datetime
from config import get_config
from .alert_types import AlertType, SeverityLevel, ALERT_TYPE_TO_SEVERITY
from .notification_service import NotificationService

class AlertManager:
    """告警管理器，负责管理所有告警的生成、存储和分发"""
    
    def __init__(self):
        """初始化告警管理器"""
        # 告警配置
        self.alert_cooldown = get_config('alerts.cooldown', 30.0)  # 告警冷却时间(秒)
        self.max_alerts_history = get_config('alerts.max_history', 1000)  # 最大历史告警数量
        self.min_severity_to_notify = get_config('alerts.min_severity_to_notify', 'warning')  # 通知的最小严重程度
        
        # 告警阈值配置
        self.severity_thresholds = {
            'cpu_usage': get_config('alerts.thresholds.cpu_usage', 80.0),
            'memory_usage': get_config('alerts.thresholds.memory_usage', 85.0),
            'fps': get_config('alerts.thresholds.fps', 10.0)
        }
        
        # 告警状态
        self.active_alerts = {}
        self.alert_history = []
        self.last_alert_time = {}
        
        # 通知服务
        self.notification_service = NotificationService()
        
        # 启用的告警类型
        self.enabled_alert_types = {
            AlertType.PEDESTRIAN_VIOLATION: get_config('alerts.enabled.pedestrian_violation', True),
            AlertType.VEHICLE_OVERLAP: get_config('alerts.enabled.vehicle_overlap', True),
            AlertType.ZONE_VIOLATION: get_config('alerts.enabled.zone_violation', True),
            AlertType.WRONG_DIRECTION: get_config('alerts.enabled.wrong_direction', False),
            AlertType.ILLEGAL_PARKING: get_config('alerts.enabled.illegal_parking', False),
            AlertType.SYSTEM_ERROR: get_config('alerts.enabled.system_error', True),
            AlertType.CAMERA_DISCONNECTED: get_config('alerts.enabled.camera_disconnected', True),
            AlertType.MODEL_LOAD_FAILURE: get_config('alerts.enabled.model_load_failure', True),
            AlertType.HIGH_CPU_USAGE: get_config('alerts.enabled.high_cpu_usage', True),
            AlertType.HIGH_MEMORY_USAGE: get_config('alerts.enabled.high_memory_usage', True),
            AlertType.LOW_FPS: get_config('alerts.enabled.low_fps', True)
        }
        
        print("告警管理器已初始化")
    
    def create_alert(self, alert_type: AlertType, severity: SeverityLevel = None,
                    source: str = "system", details: Dict = None, 
                    frame: np.ndarray = None) -> Dict:
        """创建新告警
        
        Args:
            alert_type: 告警类型
            severity: 严重程度（可选，默认为类型默认值）
            source: 告警来源
            details: 告警详细信息
            frame: 相关视频帧（可选，用于保存快照）
            
        Returns:
            创建的告警对象
        """
        # 检查告警类型是否启用
        if not self.enabled_alert_types.get(alert_type, False):
            return None
        
        # 检查冷却时间
        alert_key = f"{alert_type.value}_{source}"
        current_time = time.time()
        
        if alert_key in self.last_alert_time:
            if current_time - self.last_alert_time[alert_key] < self.alert_cooldown:
                return None
        
        # 设置默认严重程度
        if severity is None:
            severity = ALERT_TYPE_TO_SEVERITY.get(alert_type, SeverityLevel.WARNING)
        
        # 生成告警ID
        alert_id = str(uuid.uuid4())
        
        # 创建告警对象
        alert = {
            'id': alert_id,
            'type': alert_type.value,
            'severity': severity.value,
            'source': source,
            'timestamp': current_time,
            'datetime': datetime.fromtimestamp(current_time).strftime("%Y-%m-%d %H:%M:%S"),
            'details': details or {},
            'status': 'active',
            'acknowledged': False,
            'acknowledged_by': None,
            'acknowledged_at': None,
            'resolved': False,
            'resolved_at': None,
            'snapshot_path': None
        }
        
        # 保存快照
        if frame is not None:
            snapshot_path = self._save_snapshot(frame, alert_id, alert_type)
            alert['snapshot_path'] = snapshot_path
        
        # 添加到活跃告警
        self.active_alerts[alert_id] = alert
        
        # 添加到历史记录
        self.alert_history.append(alert)
        
        # 更新最后告警时间
        self.last_alert_time[alert_key] = current_time
        
        # 限制历史记录长度
        if len(self.alert_history) > self.max_alerts_history:
            self.alert_history = self.alert_history[-self.max_alerts_history:]
        
        # 发送通知
        if self._should_notify(severity):
            self.notification_service.send_notification(alert)
        
        print(f"创建告警: {alert_type.value} (ID: {alert_id})")
        
        return alert
    
    def create_violation_alert(self, violation: Dict, source: str = "behavior_analysis",
                             frame: np.ndarray = None) -> Dict:
        """创建违规告警
        
        Args:
            violation: 违规信息
            source: 告警来源
            frame: 相关视频帧
            
        Returns:
            创建的告警对象
        """
        # 根据违规类型映射到告警类型
        violation_type_to_alert_type = {
            'pedestrian_violation': AlertType.PEDESTRIAN_VIOLATION,
            'vehicle_overlap': AlertType.VEHICLE_OVERLAP,
            'zone_violation': AlertType.ZONE_VIOLATION,
            'wrong_direction': AlertType.WRONG_DIRECTION,
            'illegal_parking': AlertType.ILLEGAL_PARKING
        }
        
        alert_type = violation_type_to_alert_type.get(violation.get('type'), AlertType.ZONE_VIOLATION)
        
        # 根据严重程度设置告警级别
        severity_value = violation.get('severity', 0.5)
        if severity_value >= 0.9:
            severity = SeverityLevel.CRITICAL
        elif severity_value >= 0.7:
            severity = SeverityLevel.ERROR
        else:
            severity = SeverityLevel.WARNING
        
        # 构建详细信息
        details = violation.copy()
        
        # 创建告警
        return self.create_alert(alert_type, severity, source, details, frame)
    
    def create_system_alert(self, alert_type: AlertType, message: str,
                          details: Dict = None) -> Dict:
        """创建系统告警
        
        Args:
            alert_type: 告警类型
            message: 告警消息
            details: 详细信息
            
        Returns:
            创建的告警对象
        """
        if details is None:
            details = {}
        
        details['message'] = message
        
        return self.create_alert(alert_type, source="system", details=details)
    
    def acknowledge_alert(self, alert_id: str, user: str = "system") -> bool:
        """确认告警
        
        Args:
            alert_id: 告警ID
            user: 确认用户
            
        Returns:
            是否成功确认
        """
        if alert_id in self.active_alerts:
            alert = self.active_alerts[alert_id]
            alert['acknowledged'] = True
            alert['acknowledged_by'] = user
            alert['acknowledged_at'] = time.time()
            
            # 更新历史记录中的告警
            for i, hist_alert in enumerate(self.alert_history):
                if hist_alert['id'] == alert_id:
                    self.alert_history[i] = alert.copy()
                    break
            
            print(f"告警已确认: {alert_id} 由 {user}")
            return True
        
        return False
    
    def resolve_alert(self, alert_id: str) -> bool:
        """解决告警
        
        Args:
            alert_id: 告警ID
            
        Returns:
            是否成功解决
        """
        if alert_id in self.active_alerts:
            alert = self.active_alerts[alert_id]
            alert['status'] = 'resolved'
            alert['resolved'] = True
            alert['resolved_at'] = time.time()
            
            # 从活跃告警中移除
            del self.active_alerts[alert_id]
            
            # 更新历史记录中的告警
            for i, hist_alert in enumerate(self.alert_history):
                if hist_alert['id'] == alert_id:
                    self.alert_history[i] = alert.copy()
                    break
            
            print(f"告警已解决: {alert_id}")
            return True
        
        return False
    
    def resolve_all_alerts(self) -> int:
        """解决所有活跃告警
        
        Returns:
            解决的告警数量
        """
        alert_ids = list(self.active_alerts.keys())
        resolved_count = 0
        
        for alert_id in alert_ids:
            if self.resolve_alert(alert_id):
                resolved_count += 1
        
        print(f"已解决所有 {resolved_count} 个活跃告警")
        return resolved_count
    
    def check_system_health(self, cpu_usage: float = None, memory_usage: float = None,
                          fps: float = None) -> List[Dict]:
        """检查系统健康状态并生成相应告警
        
        Args:
            cpu_usage: CPU使用率
            memory_usage: 内存使用率
            fps: 帧率
            
        Returns:
            生成的告警列表
        """
        generated_alerts = []
        
        # 检查CPU使用率
        if cpu_usage is not None and cpu_usage > self.severity_thresholds['cpu_usage']:
            alert = self.create_system_alert(
                AlertType.HIGH_CPU_USAGE,
                f"CPU使用率过高: {cpu_usage:.1f}%",
                {'cpu_usage': cpu_usage, 'threshold': self.severity_thresholds['cpu_usage']}
            )
            if alert:
                generated_alerts.append(alert)
        
        # 检查内存使用率
        if memory_usage is not None and memory_usage > self.severity_thresholds['memory_usage']:
            alert = self.create_system_alert(
                AlertType.HIGH_MEMORY_USAGE,
                f"内存使用率过高: {memory_usage:.1f}%",
                {'memory_usage': memory_usage, 'threshold': self.severity_thresholds['memory_usage']}
            )
            if alert:
                generated_alerts.append(alert)
        
        # 检查帧率
        if fps is not None and fps < self.severity_thresholds['fps']:
            alert = self.create_system_alert(
                AlertType.LOW_FPS,
                f"帧率过低: {fps:.1f} FPS",
                {'fps': fps, 'threshold': self.severity_thresholds['fps']}
            )
            if alert:
                generated_alerts.append(alert)
        
        return generated_alerts
    
    def _save_snapshot(self, frame: np.ndarray, alert_id: str, alert_type: AlertType) -> str:
        """保存告警快照
        
        Args:
            frame: 视频帧
            alert_id: 告警ID
            alert_type: 告警类型
            
        Returns:
            保存路径
        """
        import os
        
        # 创建快照目录
        snapshots_dir = get_config('alerts.snapshots_dir', './snapshots')
        os.makedirs(snapshots_dir, exist_ok=True)
        
        # 生成文件名
        timestamp = datetime.now().strftime("%Y%m%d_%H%M%S")
        filename = f"{alert_type.value}_{timestamp}_{alert_id[:8]}.jpg"
        filepath = os.path.join(snapshots_dir, filename)
        
        # 保存图像
        try:
            cv2.imwrite(filepath, frame)
            print(f"已保存告警快照: {filepath}")
            return filepath
        except Exception as e:
            print(f"保存快照失败: {str(e)}")
            return None
    
    def _should_notify(self, severity: SeverityLevel) -> bool:
        """判断是否应该发送通知
        
        Args:
            severity: 告警严重程度
            
        Returns:
            是否应该发送通知
        """
        severity_levels = list(SeverityLevel)
        min_level_index = severity_levels.index(SeverityLevel[self.min_severity_to_notify.upper()])
        current_level_index = severity_levels.index(severity)
        
        return current_level_index >= min_level_index
    
    def get_active_alerts(self, alert_type: AlertType = None, 
                         severity: SeverityLevel = None) -> List[Dict]:
        """获取活跃告警
        
        Args:
            alert_type: 告警类型筛选
            severity: 严重程度筛选
            
        Returns:
            告警列表
        """
        alerts = list(self.active_alerts.values())
        
        if alert_type:
            alerts = [a for a in alerts if a['type'] == alert_type.value]
        
        if severity:
            alerts = [a for a in alerts if a['severity'] == severity.value]
        
        # 按时间倒序排序
        alerts.sort(key=lambda x: x['timestamp'], reverse=True)
        
        return alerts
    
    def get_stats(self) -> Dict[str, int]:
        """获取告警统计信息
        
        Returns:
            包含告警统计信息的字典，包括不同严重程度的活跃告警数量
        """
        stats = {
            'total_alerts': len(self.active_alerts),
            'critical_count': 0,
            'error_count': 0,
            'warning_count': 0,
            'info_count': 0
        }
        
        # 统计不同严重程度的告警数量
        for alert in self.active_alerts.values():
            severity = alert.get('severity', '').lower()
            if severity == 'critical':
                stats['critical_count'] += 1
            elif severity == 'error':
                stats['error_count'] += 1
            elif severity == 'warning':
                stats['warning_count'] += 1
            elif severity == 'info':
                stats['info_count'] += 1
        
        return stats
    
    def get_alert_history(self, limit: int = None, alert_type: AlertType = None,
                         severity: SeverityLevel = None) -> List[Dict]:
        """获取告警历史
        
        Args:
            limit: 返回数量限制
            alert_type: 告警类型筛选
            severity: 严重程度筛选
            
        Returns:
            告警历史列表
        """
        alerts = self.alert_history.copy()
        
        if alert_type:
            alerts = [a for a in alerts if a['type'] == alert_type.value]
        
        if severity:
            alerts = [a for a in alerts if a['severity'] == severity.value]
        
        # 按时间倒序排序
        alerts.sort(key=lambda x: x['timestamp'], reverse=True)
        
        if limit:
            alerts = alerts[:limit]
        
        return alerts
    
    def set_alert_cooldown(self, cooldown: float) -> None:
        """设置告警冷却时间
        
        Args:
            cooldown: 冷却时间（秒）
        """
        self.alert_cooldown = cooldown
    
    def set_max_history(self, max_history: int) -> None:
        """设置最大历史记录数量
        
        Args:
            max_history: 最大历史记录数量
        """
        self.max_alerts_history = max_history
        
        # 如果当前历史记录超过限制，进行截断
        if len(self.alert_history) > max_history:
            self.alert_history = self.alert_history[-max_history:]
    
    def set_min_severity_to_notify(self, severity: str) -> None:
        """设置通知的最小严重程度
        
        Args:
            severity: 严重程度字符串 (info, warning, error, critical)
        """
        if severity.lower() in [level.value for level in SeverityLevel]:
            self.min_severity_to_notify = severity.lower()
    
    def set_thresholds(self, cpu_usage: float = None, memory_usage: float = None,
                      fps: float = None) -> None:
        """设置系统健康检查阈值
        
        Args:
            cpu_usage: CPU使用率阈值
            memory_usage: 内存使用率阈值
            fps: 帧率阈值
        """
        if cpu_usage is not None:
            self.severity_thresholds['cpu_usage'] = cpu_usage
        if memory_usage is not None:
            self.severity_thresholds['memory_usage'] = memory_usage
        if fps is not None:
            self.severity_thresholds['fps'] = fps
    
    def set_alert_type_enabled(self, alert_type: AlertType, enabled: bool) -> None:
        """设置告警类型是否启用
        
        Args:
            alert_type: 告警类型
            enabled: 是否启用
        """
        self.enabled_alert_types[alert_type] = enabled
    
    def clear_alert_history(self) -> None:
        """清除告警历史"""
        self.alert_history.clear()
        print("告警历史已清除")
        
    def get_stats(self) -> Dict[str, Any]:
        """获取告警管理器统计信息
        
        Returns:
            包含告警统计信息的字典
        """
        # 统计各类型活跃告警数量
        type_stats = {}
        for alert in self.active_alerts.values():
            alert_type = alert['type']
            if alert_type not in type_stats:
                type_stats[alert_type] = 0
            type_stats[alert_type] += 1
            
        # 统计各严重程度活跃告警数量
        severity_stats = {}
        for alert in self.active_alerts.values():
            severity = alert['severity']
            if severity not in severity_stats:
                severity_stats[severity] = 0
            severity_stats[severity] += 1
            
        return {
            'active_alerts_count': len(self.active_alerts),
            'alert_history_count': len(self.alert_history),
            'active_alerts_by_type': type_stats,
            'active_alerts_by_severity': severity_stats,
            'alert_cooldown': self.alert_cooldown,
            'max_history': self.max_alerts_history,
            'min_severity_to_notify': self.min_severity_to_notify,
            'severity_thresholds': self.severity_thresholds,
            'enabled_alert_types': {k.value: v for k, v in self.enabled_alert_types.items()}
        }

# 创建全局告警管理器实例
alert_manager = AlertManager()

# 导出常用方法
def get_alert_manager() -> AlertManager:
    """获取告警管理器实例的快捷方法"""
    return alert_manager